package com.qf.strategy.service.Impl;


import com.qf.strategy.feign.CacheService;
import com.qf.strategy.service.DataFilterManager;
import com.qf.strategy.service.FilterChain;
import com.qf.strategy.utils.FilterOrdersUtil;
import com.qianfeng.smsplatform.common.constants.CacheConstants;
import com.qianfeng.smsplatform.common.model.Standard_Submit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.zip.DataFormatException;

/**
 * Created by jackiechan on 2020-02-27 11:00
 *
 * @Author jackiechan
 */
@Service
public class DataFilterManagerImplFromRedisWithJVMCache implements DataFilterManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(DataFilterManagerImplFromRedisWithJVMCache.class);
    @Autowired
    private CacheService cacheService;
    //一个保存着名字和过滤器之间映射关系的 map,spring会自动创建我们所有声明了相关注解的对象,然后对象会被保存到map 中,按照名字会保存一份,默认是类型的首字母小写
    @Autowired
    private Map<String, FilterChain> filterChainMap;


    @Override
    public void dealSms(Standard_Submit submit) {
        //当前情况下,我们的用户信息中保存的就不是具体经过哪些过滤器,因为我们需要经过的过滤器是单独按组放起来的,我们只需要知道是哪一组过滤器即可
        // 获取当前用户的过滤器的分组
        String filtersorder = cacheService.hget(CacheConstants.CACHE_PREFIX_CLIENT + submit.getClientID(), "filtersorder");
        if (filtersorder == null) {
            LOGGER.error("当前用户{}没有对应的过滤器分组", submit.getClientID());
            return;
        }
        //根据分组的 id 去获取用户需要经过的过滤器的顺序
        //过滤器的分组数据我们也放在了 redis中,按理来说我们应该从 redis 中获取,但是我们经过分析知道这个分组的数据基本上是不变的,
        // 所以我们去查询 redis 查询多次得到的结果是一样的,所以我们就没有必要每次都去查询 redis,我们可以在本地做一次缓存
        // 现在我们应该从本地缓存中找
        //分析:本地缓存中的数据是怎么来的,什么时候来的


        //因为我们不知道什么时候回来短信,而且我们必须保证来短信的时候就必须已经有本地缓存数据了,就相当于我们的手机收短信一样,我们不知道什么时候回来短信,所以我们在手机开机的时候卡就必须插好
        //按照上面的逻辑,在我们程序启动的时候就必须加载缓存数据
        //从本地缓存中获取到当前用户对应的 id 的过滤器
        String filters = FilterOrdersUtil.filtersOrderMap.get(CacheConstants.CACHE_PREFIX_SMS_FILTERS_ORDER + filtersorder);

        String[] requirFilters = filters.split(",");//获取到所有需要经过的过滤器,数据中顺序就是过滤器顺序

        if (requirFilters != null && submit != null) {
            for (String filter : requirFilters) { //遍历我们需要经过的所有的过滤器的字符串,拿到的每个字符串就是过滤器的名字,拿到的顺序就是过滤器的顺序

                try {
                    //根据名字来获取到当前这个过滤器
                    FilterChain filterChain = filterChainMap.get(filter);
                    if (filterChain != null) {
                        boolean result = filterChain.dealSms(submit);
                        //如果返回结果是 false 代表当前过滤器校验失败,我们应该跳出循环,直接返回,因为后面的过滤器就没有必要校验了
                        if (!result) {
                            LOGGER.error("过滤器返回了fasle:{}", filterChain);
                            break;
                        }
                    }
                } catch (DataFormatException e) {
                    e.printStackTrace();
                    LOGGER.error("过滤器发生异常:{}", e.getMessage());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
